﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Evolution.Structure.Globe.Details;
using Evolution.Structure.Globe.Units;
using Evolution.Structure.Globe;
using System.Xml;
using System.Windows;
using Evolution.Structure.Globe.Fields;


namespace Evolution.Structure
{
    public class Encyclopedia
    {
        public List<Nation> NationList { get; set; }
        public List<Building> BuildingList { get; set; }
        public List<Unit> UnitList { get; set; }
        public List<Technology> TechnologyList { get; set;}

        public Encyclopedia()
        {
            NationList = new List<Nation>();
            BuildingList = new List<Building>();
            UnitList = new List<Unit>();
            TechnologyList = new List<Technology>();

            Init();
        }
        private XmlDocument nationDoc = new XmlDocument();
        private XmlDocument techDoc = new XmlDocument();


        private void Init()
        {
            #region TechnologyLoader
            /*
             * TECHNOLOGY-LOADER
             * BEGIN
             */
            Dictionary<string, Technology> techDict = new Dictionary<string, Technology>();

            List<Technology> techPredecessors = new List<Technology>();
            techDoc.Load(@"xml\Technologies.xml");

            XmlNodeList allTechs = techDoc.SelectNodes("/Technologies/Technologie");
            foreach (XmlNode singleTechNode in allTechs)
            {
                //Vorbedingung: XML in Beziehung Predecessors sortiert

                // Predecessors
                List<Technology> predecessorList = new List<Technology>();
                XmlNodeList predecessors = singleTechNode.SelectNodes("Predecessors");
                if(predecessors.Count != 0)
                    foreach(XmlNode predecessor in predecessors)
                    {
                        if(predecessor.InnerText != null)
                        predecessorList.Add(techDict[predecessor.InnerText]);
                    }

                try
                {
                    String TechName = singleTechNode.SelectSingleNode("Name").InnerText;
                    int costs = Convert.ToInt32(singleTechNode.SelectSingleNode("ResearchCosts").InnerText);
                    // Actual Technology
                    Technology newTech = new Technology(
                        TechName, 
                        costs, 
                        predecessorList);
                    // einfügen in das Dictionary und in die Liste aller Technologien
                    techDict.Add(singleTechNode.SelectSingleNode("Name").InnerText, newTech);
                    TechnologyList.Add(newTech); }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
                         
            }
            /*
             * TECHNOLOGY-LOADER
             * END
             */
            #endregion TechnologyLoader
            #region Nationloader
            /*
             * NATIONLOADER
             * BEGIN
             */
            

            nationDoc.Load(@"xml\Nations.xml");

            XmlNodeList nationsNodeList = nationDoc.SelectNodes("/Nations/Nation");
            XmlNodeList startTechNode;
            XmlNodeList benefitNodes;
            XmlNodeList cityNameNodes;

            foreach (XmlNode node in nationsNodeList)
            {

                Nation tempNation;

                string name = "";
                int seedMoney = 0;
                List<Technology> startingTechnologies = new List<Technology>();
                List<Unit> startingUnits = new List<Unit>();
                List<Benefit> benefits = new List<Benefit>();
                List<string> cityNames = new List<string>();



                name = node.SelectSingleNode("Name").InnerText;
                seedMoney = Convert.ToInt32(node.SelectSingleNode("Seedmoney").InnerText);
                
                // Starting Technologies
                startTechNode = node.SelectNodes("StartingTechs/StartingTech");
                foreach (XmlNode startingTechnologiesNode in startTechNode)
                {
                    startingTechnologies.Add(techDict[startingTechnologiesNode.InnerText]);
                }

                //TO-DO: Units ertsellen

                // Benefits
                benefitNodes = node.SelectNodes("Benefits/Benefit");
                foreach (XmlNode benefitNode in benefitNodes)
                {
                    Evolution.Structure.Globe.ValueType vt = Globe.ValueType.Relative;
                    if ((benefitNode.Attributes["valuetype"].InnerText).ToLower() == "absolute")
                         vt = Evolution.Structure.Globe.ValueType.Absolute;
                    if ((benefitNode.Attributes["valuetype"].InnerText).ToLower() == "relative")
                         vt = Evolution.Structure.Globe.ValueType.Relative; 
                    string benefitName = benefitNode.Attributes["name"].InnerText;
                    string benefitDescription =  benefitNode.InnerText;
                    int benefitValue = Convert.ToInt32(benefitNode.Attributes["value"].InnerText);
                    benefits.Add(
                        new Benefit(
                            benefitName, 
                           benefitDescription, 
                            vt, 
                            benefitValue
                            ));
                    
                }

                // List of Citiynames
                cityNameNodes = node.SelectNodes("CityNames/CityName");
                foreach (XmlNode cityNameNode in cityNameNodes)
                {
                    cityNames.Add(cityNameNode.InnerText);
                }

                tempNation = new Nation(name, seedMoney, startingTechnologies, startingUnits, benefits, cityNames);
                NationList.Add(tempNation);
                

            }
            /*
             * NATIONLOADER
             * END
             */
            #endregion Nationloader
            #region Buildingloader
            /*
             * BUILDINGLOADER
             * BEGIN
             */

            XmlDocument buildingDoc = new XmlDocument();
            buildingDoc.Load(@"xml\Buildings.xml");
            Dictionary<string, Building> buildingDict = new Dictionary<string, Building>();


            XmlNodeList buildingsNodeList = buildingDoc.SelectNodes("/Buildings/Building");

            foreach (XmlNode node in buildingsNodeList)
            {
                String BuildingName = node.SelectSingleNode("Name").InnerText;
                Int32 BuidingsCosts = Convert.ToInt32(node.SelectSingleNode("BuildingCosts").InnerText);
                List<Benefit> benefitsList = new List<Benefit>();
                List<Technology> techList = new List<Technology>();

                // Needed Technologies
                XmlNodeList techNodesList = node.SelectNodes("Technologies/Technology");
                foreach (XmlNode techNode in techNodesList)
                {
                    techList.Add(techDict[techNode.InnerText]);
                }
            
                // Benefits
                XmlNodeList buildingBenefitsNodesList = node.SelectNodes("Benefits/Benefit");
                foreach (XmlNode benefitNode in buildingBenefitsNodesList)
                {
                    Evolution.Structure.Globe.ValueType vt = Globe.ValueType.Relative;
                    if ((benefitNode.Attributes["valuetype"].InnerText).ToLower() == "absolute")
                        vt = Evolution.Structure.Globe.ValueType.Absolute;
                    if ((benefitNode.Attributes["valuetype"].InnerText).ToLower() == "relative")
                        vt = Evolution.Structure.Globe.ValueType.Relative;
                    string benefitName = benefitNode.Attributes["name"].InnerText;
                    string benefitDescription = benefitNode.InnerText;
                    int benefitValue = Convert.ToInt32(benefitNode.Attributes["value"].InnerText);
                    benefitsList.Add(
                        new Benefit(
                            benefitName,
                           benefitDescription,
                            vt,
                            benefitValue
                            ));

                }

                Building tempBuilding = new Building();
                tempBuilding.Benefits = benefitsList;
                tempBuilding.BuildingCosts = BuidingsCosts;
                tempBuilding.Name = BuildingName;
                tempBuilding.RequiredTechnologies = techList;

                buildingDict.Add(tempBuilding.Name, tempBuilding);
                BuildingList.Add(tempBuilding);
            }
            /*
             * BUILDINGLOADER
             * END
             */
            #endregion Buildingloader
            #region UnitLoader
            /*
            * UNITLOADER
            * BEGIN
            */
            try{
                XmlDocument unitDoc = new XmlDocument();
                unitDoc.Load(@"xml\Units.xml");

                XmlNodeList UnitNodesList = unitDoc.SelectNodes("/Units/Unit");
                Dictionary<string, Unit> unitDict = new Dictionary<string, Unit>();

                foreach (XmlNode node in UnitNodesList)
                    {
                        //XmlNodeList techNodesList = node.SelectNodes("Attackables/Attackable");
                        //foreach (XmlNode techNode in techNodesList)
                        //{
                        //   // TODO: Gibts im Classdiagram (noch) nicht
                        //}
                        String unitName = node.SelectSingleNode("Name").InnerText;
                        Int32 AttackPoint = Convert.ToInt32(node.SelectSingleNode("AttackPoint").InnerText);
                        Int32 AttackRange = Convert.ToInt32(node.SelectSingleNode("AttackRange").InnerText);
                        int BuildingCosts = Convert.ToInt32(node.SelectSingleNode("BuildingCosts").InnerText);
                        Boolean CargoAble = Convert.ToBoolean(node.SelectSingleNode("CargoAble").InnerText);
                        int CanCargo = Convert.ToInt32(node.SelectSingleNode("CanCargo").InnerText);
                        int DefensePoints = Convert.ToInt32(node.SelectSingleNode("DefensePoints").InnerText);
                        String AvailableForNations = node.SelectSingleNode("AvailableForNations").InnerText;
                        int Health = Convert.ToInt32(node.SelectSingleNode("Health").InnerText);
                        int MovePoints = Convert.ToInt32(node.SelectSingleNode("MovePoints").InnerText);
                        double MaintenanceCosts = Convert.ToDouble(node.SelectSingleNode("MaintenanceCosts").InnerText);
                        String MoveableOn = node.SelectSingleNode("MoveableOn").InnerText;

                        List<Building> RequiredBuildingsList = new List<Building>();
                        XmlNodeList RequiredBuildingsNodeList = node.SelectNodes("RequiredBuildings/RequiredBuilding");
                        foreach (XmlNode RequiredBuildingNode in RequiredBuildingsNodeList)
                        {
                            String searchString = RequiredBuildingNode.InnerText;
                            RequiredBuildingsList.Add(buildingDict[searchString]);
                        }

                        List<Technology> RequiredTechnologiesList = new List<Technology>();
                        XmlNodeList RequiredTechnologiesNodeList = node.SelectNodes("RequiredTechnologies/RequiredTechnologie");

                        foreach (XmlNode RequiredTechnologieNode in RequiredTechnologiesNodeList)
                        {
                            RequiredTechnologiesList.Add(techDict[RequiredTechnologieNode.InnerText]);
                        }

                        //unit: <UpgradeableTo>Maceman</UpgradeableTo>

                        Unit tempUnit = new Unit();
                        tempUnit.Name = unitName;
                        //tempUnit.AttackPoints = AttackPoint;
                        //tempUnit.AttackRange = AttackRange;
                        //tempUnit.AvailableForNation = AvailableForNations;
                        tempUnit.BuildingCosts = BuildingCosts;
                        //tempUnit.CargoAbleUnits = 
                        tempUnit.CargoSpace = CanCargo;
                        //tempUnit.DefensePoints
                        tempUnit.MaintenanceCosts = Convert.ToDouble(MaintenanceCosts);
                        tempUnit.MovePoints = MovePoints;
                        tempUnit.RequiredBuildings = RequiredBuildingsList;
                        tempUnit.Requiredtechnologies = RequiredTechnologiesList;

                        String upgradableToString = node.SelectSingleNode("UpgradeableTo").InnerText;
                        if (upgradableToString != "")
                            tempUnit.UpgradeableToUnit = unitDict[upgradableToString];

                        UnitList.Add(tempUnit);
                        unitDict.Add(tempUnit.Name, tempUnit);
                    }
                }
                catch(Exception e) 
                { 
                    MessageBox.Show(e.Message); 
                }
                
            /*
            * UNITLOADER
            * END
            */
            #endregion UnitLoader
            }



        }
    }


